﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using VAdvantage.Model;
using VAdvantage.UIEvent;
using VAdvantage.Controls;
using VAdvantage.Grids;

namespace VAdvantage.Editor
{
    public abstract class WEditor : IValueChanged, IEventLitnerer
    {

        public event ValueChangedEventHandler VetoableChangeListner;
        

        public void OnValueChanged(ValueChangedEvent vce)
        {
            if (VetoableChangeListner != null)
            {
            }

        }

        public const int MAX_DISPLAY_LENGTH = 35;

        protected GridField gridField;

        protected GridTab gridTab;

        protected VLabel label;

        protected UIElement control;

        protected bool mandatory;

        private String strLabel;

        private String description;

        private bool readOnly;

        private bool updateable;

        private String columnName;

        protected bool hasFocus;
        

        public WEditor(UIElement comp, GridField gridField)
        {
            if (comp == null)
            {
                throw new ArgumentNullException("Component cannot be null");
            }

            if (gridField == null)
            {
                throw new ArgumentNullException("Grid field cannot be null");
            }

            this.SetControl(comp);
            this.gridField = gridField;
            this.SetMandatory(gridField.IsMandatory(false));
            this.readOnly = gridField.IsReadOnly();
            this.description = gridField.GetDescription();
            this.updateable = gridField.IsUpdateable();
            this.columnName = gridField.GetColumnName();
            this.strLabel = gridField.GetHeader();
            Init();
        }

        /**
         * Method is used to distinguish between 2 similar WSearchEditors
         *
         */
        public String GetDescription()
        {
            return description;

        }

        /**
         * Constructor for use if a grid field is unavailable
         *
         * @param comp			The editor's control
         * @param label			column name (not displayed)
         * @param description	description of control
         * @param mandatory		whether a selection must be made
         * @param readonly		whether or not the editor is read only
         * @param updateable	whether the editor contents can be changed
         */
        public WEditor(UIElement comp, String label, String description, bool mandatory, bool ro, bool updateable)
        {
            if (comp == null)
            {
                throw new ArgumentException("Component cannot be null");
            }

            this.SetControl(comp);
            this.SetMandatory(mandatory);
            this.readOnly = ro;
            this.description = description;
            this.updateable = updateable;
            this.strLabel = label;
            Init();
        }

        public WEditor(UIElement comp, String columnName, String label, String description, bool mandatory, bool ro, bool updateable)
        {
            if (comp == null)
            {
                throw new ArgumentException("Component cannot be null");
            }

            this.SetControl(comp);
            this.SetMandatory(mandatory);
            this.readOnly = ro;
            this.description = description;
            this.updateable = updateable;
            this.strLabel = label;
            this.columnName = columnName;
            Init();
        }

        

        protected void SetControl(UIElement comp)
        {
            this.control = comp;
        }

        private void Init()
        {
            label = new VLabel(strLabel);

            this.SetMandatory(mandatory);

            if (readOnly || !updateable)
            {
                this.SetReadWrite(false);
            }
            else
            {
                this.SetReadWrite(true);
            }

            ToolTipService.SetToolTip(control, description);

            ToolTipService.SetToolTip(label, description);

            control.GotFocus += delegate
            {
                hasFocus = true;
            };

            control.LostFocus += delegate
            {
                hasFocus = false;
            };
        }

        

        //control.addEventListener(Events.ON_FOCUS, new EventListener() {
        //    public void onEvent(Event event) throws Exception {
        //        hasFocus = true;
        //    }

        //});
        //control.addEventListener(Events.ON_BLUR, new EventListener() {
        //    public void onEvent(Event event) throws Exception {
        //        hasFocus = false;
        //    }

        //       });
        //}

        public GridField GetGridField()
        {
            return gridField;
        }

        public String GetColumnName()
        {
            return columnName;
        }

        protected String CleanColumnName(String originalColumnName)
        {
            String cleanColumnName;
            /*
             *  The regular expression to use to find the table qualifier.
             *  Matches "<table name>."
             */
            const String regexTablePrefix = ".*\\.";

            cleanColumnName = originalColumnName.Replace(regexTablePrefix, "");

            return cleanColumnName;
        }

        protected void SetColumnName(String columnName)
        {
            String cleanColumnName = CleanColumnName(columnName);
            this.columnName = cleanColumnName;
        }

        public IControl GetControl()
        {
            return (IControl)control;
        }

        public void SetGridTab(GridTab gridTab)
        {
            this.gridTab = gridTab;
        }

        public ContextMenu GetPopupMenu()
        {
            return null;
        }

        public VLabel GetLabel()
        {
            return label;
        }

        public abstract void SetReadWrite(bool readWrite);

        public abstract bool IsReadWrite();

        public abstract void OnEvent(Event e);

        public void SetPopup(ContextMenuStrip   context)           
        {
            ContextMenuService.SetContextMenu(control, context);
        }

        public void SetVisible(bool visible)
        {
            label.SetVisible(visible);// .Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
            ((IControl)control).Visible=visible;//     .Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
        }

        /**
         *
         * @return is visible
         */
        public bool IsVisible()
        {
            return control.Visibility == Visibility.Visible;
        }

        public virtual void SetBackground(bool error)
        {

        }

        public virtual void SetBackground(Color color)
        {

        }

        public override String ToString()
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder(30);
            sb.Append(this.GetType().FullName);
            sb.Append("[").Append(this.GetColumnName());
            sb.Append("=");
            sb.Append(this.GetValue()).Append("]");
            return sb.ToString();
        }

        /**
         *
         * @param value
         */
        abstract public void SetValue(Object value);

        /**
         *
         * @return Object
         */
        abstract public Object GetValue();

        /**
         *
         * @return display text
         */
        abstract public String GetDisplay();



        /**
         * Set whether the editor represents a mandatory field.
         * @param mandatory whether the field is mandatory
         */
        public void SetMandatory(bool mandatory)
        {
            this.mandatory = mandatory;
            if (label != null)
                label.SetMandatory(mandatory && IsReadWrite());
        }

        /**
         *
         * @return boolean
         */
        public bool IsMandatory()
        {
            return this.mandatory;
        }

        /**
         * allow subclass to perform dynamic loading of data
         */
        public void DynamicDisplay()
        {
        }


        public bool IsHasFocus()
        {
            return hasFocus;
        }

        public void SetHasFocus(bool b)
        {
            hasFocus = b;
        }

        public UIElement GetUIElement()
        {
            return  this.control;
        }

        
    }
}
